package main;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.Scanner;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;

import pieces.Horse;
import board.Board;


//falta criar a condicao de existir outra peca no caminho
//checar na hora do grafo
public class Main {

	static ArrayList<Horse> queue = new ArrayList<Horse>();
	static String graph = "digraph Caminhamento_em_Tabuleiro_de_Xadrez {rankdir=LR\n";
	static int[] wrongPosition = { -1, -1 };

	// set a horse on a board
	public static void setOnBoard(Board board, int[] position, Horse horse) {
		board.setInPosition(position[0], position[1], horse);

	}

	public static void blockPosition(Board board, int x, int y) {
		Horse wrongHorse = new Horse(null, wrongPosition);
		int[] position = { x, y };
		setOnBoard(board, position, wrongHorse);
	}

	public static void nextMoves(Horse piece, Board board) {
		int[] position = piece.getPosition();
		int[] valoresMove = { -2, -1, 1, 2 };

		int i0 = position[0];
		int j0 = position[1];
		int[] nextsI = new int[8];
		int[] nextsJ = new int[8];

		int counter = 0;

		// i0 eh a posicao atual da peca

		// nesse for gera-se as 8 possiveis proximas casas incluindo posicoes
		// negativas e q passam do limite do tabuleiro
		// para q dps seja testada estas possibilidades
		for (int i = 0; i < 8; i += 2) {
			int nextMove = valoresMove[counter];

			counter++;

			nextsI[i] = i0 + nextMove;
			nextsI[i + 1] = i0 + nextMove;

			if (Math.abs(nextMove) == 1) {
				nextsJ[i] = j0 + 2;
				nextsJ[i + 1] = j0 - 2;
			} else {
				nextsJ[i] = j0 + 1;
				nextsJ[i + 1] = j0 - 1;
			}

		}

		// nesse for testa-se todas as possibilidades e cria um novo cavalo na
		// posicao possivel
		// add o nextHorse na queue pra os proximos calculos
		for (int i = 0; i < 8; i++) {
			int nextI = nextsI[i];
			int nextJ = nextsJ[i];

			if (nextI > 7 || nextJ > 7 || nextI < 0 || nextJ < 0) {
				continue;
			}
			Horse test = board.getInPosition(nextI, nextJ);
			if (test != null && test.getPosition() == wrongPosition) {

				continue;
			} else {
				if (board.getInPosition(nextI, nextJ) == null) {
					int[] nextPosition = { nextI, nextJ };
					Horse nextHorse = new Horse(piece, nextPosition);
					queue.add(nextHorse);
					setOnBoard(board, nextPosition, nextHorse);

				} else {
					continue;
				}

			}

		}
	}
	//x0 e y0 sao as posicoes iniciais
	public static String makeString(Board board,int x0, int y0) {
		Horse firstPiece = null;
		for (int i = 0; i < board.getHeight(); i++) {

			for (int j = 0; j < board.getWidth(); j++) {
				Horse first = board.getInPosition(i, j);
				if (first != null && first.getPrevPiece() != null) {
					graph += "\"" + first.getPrevPiece() + "\"";
					graph += " -> ";
					graph += "\"" + first + "\"";
					graph += ";\n";
				}
			
			}
		}if(graph.length() > 57) {
			graph += "}";
			return graph;
		}		
		else {
			graph += "\"" + board.getInPosition(x0, y0) + "\"";
			graph += "}";
			return graph;
		}
		
	}
	
	public static int[] recebePosicaoInicial() {
		System.out.println("Digite a posicao por onde deseja comecar o caminhamento: (Exemplo: (2,3))");
		Scanner sc = new Scanner(System.in);
		String posicaoInicial = sc.nextLine();
		posicaoInicial = posicaoInicial.replace(" ", "").replace("(", "").replace(")", "");
		
		String[] posicaoInicialArray = posicaoInicial.split(",");
		if ( posicaoInicialArray.length != 2) {
			System.out.println("Posicao Invalida");
			return recebePosicaoInicial();
		}
		int[] posicao = new int[2];
		for (int i = 0; i < posicaoInicialArray.length; i++) {
			try {
				posicao[i] = Integer.parseInt(posicaoInicialArray[i]);
				if (posicao[i] > 7 || posicao[i] < 0) {
					throw new Exception();
				}
			} catch (Exception e) {
				System.out.println("Posicao Invalida");
				return  recebePosicaoInicial();
			}			
		}
		return posicao;
	}
	
	public static void ocupaCasas(Board board, int[] initialPositon) {
		System.out.println("Digite as posicoes que deseja ocupar: (Exemplo: (2,3), (2,4), (5,4)) ");
		Scanner sc = new Scanner(System.in);
		String posicoes = sc.nextLine();
		posicoes = posicoes.replace(" ", "").replace("(", "").replace(")", "");
		String[] arrayPosicoes = posicoes.split(",");
		if(arrayPosicoes.length % 2 != 0) {
			System.out.println("Posicoes invalidas");
			ocupaCasas(board,initialPositon);
		}
		for (int k = 0; k < arrayPosicoes.length; k += 2) {
			try {
				int i = Integer.parseInt(arrayPosicoes[k]);
				int j = Integer.parseInt(arrayPosicoes[k + 1]);
				if(i < 0 || j < 0 || i > 7 || j > 7) {
					throw new Exception(); 
				}
				if(i == initialPositon[0] && j == initialPositon[1]) {
					System.out.println("Voce nao pode ocupar a posicao inicial");
					ocupaCasas(board,initialPositon);
				}
				blockPosition(board, i, j);
			} catch (Exception e) {
				System.out.println("Posicoes invalidas");
				ocupaCasas(board,initialPositon);
			}
		}		
	}
	
	public static void recebeOpcao(Board board, int[] initialPosition) {
		System.out.println("Deseja ocupar alguma casa? (S/N)");
		Scanner sc = new Scanner(System.in);
		String opcao = sc.nextLine().toUpperCase();
		if(opcao.equals("S")) {
			ocupaCasas(board, initialPosition);
		}
		else if (opcao.equals("N"));
		else {
			System.out.println("Opcao Invalida");
			recebeOpcao(board, initialPosition);
		}
		
		
	}

	public static void main(String[] args) throws IOException {

		int[] initialPosition = recebePosicaoInicial();
		Horse initialPiece = new Horse(null, initialPosition);

		Board board = new Board(8, 8);
		// setup inicial
		setOnBoard(board, initialPosition, initialPiece);
		
		recebeOpcao(board,initialPosition);
		
		long tempoInicial = System.currentTimeMillis();  


		 

		nextMoves(initialPiece, board);

		//		
		// System.out.println(board);
		Iterator<Horse> it = queue.iterator();
		while (it.hasNext()) {
			Horse next = it.next();
			nextMoves(next, board);
			queue.remove(next);
			it = queue.iterator();
		}
		
		FileWriter fw = new FileWriter(new File("grafo"), false);
		fw.write(makeString(board, initialPosition[0], initialPosition[1]));
		fw.close();
		
		long tempoFinal = System.currentTimeMillis();  
		System.out.printf("Tempo de execucao: %.3f ms%n", (tempoFinal - tempoInicial) / 1000d); 

	}

}
